package com.yige.web.controller

import com.mongodb.BasicDBObject
import com.mongodb.DBObject
import com.yige.common.ArgsUtil
import com.yige.common.MD5Util
import com.yige.common.ResultUtil
import com.yige.common.SystemConstant
import com.yige.common.ToDBObjectUtil
import com.yige.service.mongoService.MongoLessonService
import com.yige.service.mongoService.MongoLessonStuService
import com.yige.service.mongoService.MongoPayLogService
import com.yige.service.mongoService.MongoRecordService
import com.yige.service.mongoService.MongoStudentService
import com.yige.service.mongoService.MongoTeacherService
import com.yige.service.mongoService.MongoUserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.util.StringUtils
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.ResponseBody

/**
 * Created by sunhao on 2015/9/20 0020.
 */

@Controller
@RequestMapping("student")
class StudentController {

    @Autowired
    MongoStudentService studentService
    @Autowired
    MongoTeacherService teacherService
    @Autowired
    MongoLessonStuService lessonService
    @Autowired
    MongoUserService userService
    @Autowired
    MongoRecordService recordService
    @Autowired
    MongoPayLogService payLogService

    /*************控制器模块************/

    /**
     * 显示学生管理页面
     * @param model
     * @return
     */
    @RequestMapping("list.do")
    def list(Model model) {
        def studentList = studentService.findList() as LinkedList
        def students = studentListArgs(studentList)
        model.addAttribute("students", students)
        select(model)
        return "student/list"
    }

    /**
     * 多条件联合查询学生
     * @param model
     * @param name
     * @param lessonId
     * @param teacherId
     * @return
     */
    @RequestMapping("find")
    def find(Model model, String name, String lessonId, String teacherId) {
        def query = new BasicDBObject()
        if (!StringUtils.isEmpty(name)) {
            query.append("name", ~/${name}/)
        }
        if (!StringUtils.isEmpty(lessonId)) {
            query.append("lessons.id", [$in: [lessonId]] as BasicDBObject)
        }
        if (!StringUtils.isEmpty(teacherId)) {
            query.append("teachers", [$in: [teacherId]] as BasicDBObject)
        }
        def studentList = studentService.findListByQuery(query) as LinkedList
        model.addAttribute("students", studentList)
        select(model)
        return "student/list"
    }

    /**
     * 添加学生
     * @param name
     * @param phone
     * @param identityCard
     * @return
     */
    @RequestMapping("addStudent")
    @ResponseBody
    def addStudent(String name, String phone, String identityCard) {
        //创建学生信息
        def teachers = new ArrayList(), lessons = new ArrayList(), payInfo = new ArrayList()
        boolean isUsed = false, flag = false
        def check = studentService.findList()
        //检查是否有同名学生
        check.each {
            if (it.name == name) {
                isUsed == true
            }
        }
        //没有则继续
        if (isUsed == false) {
            Map<String, Object> studentInfo = [_id         : UUID.randomUUID().toString(),
                                               name        : name,
                                               phone       : phone,
                                               identityCard: identityCard,
                                               teachers    : teachers,
                                               lessons     : lessons,
                                               payInfo     : payInfo,
                                               status      : SystemConstant.STUDENT_STATUS_ON]
            DBObject dbObject = ToDBObjectUtil.toDBObject(studentInfo)
            addStudentToUser(name, phone, studentInfo.get("_id"))
            flag = saveStudent(dbObject)
        }
        ResultUtil.recallAjax(flag)
    }

    /**
     * 删除学生
     * @param _ids
     * @return
     */
    @RequestMapping("delStudent")
    @ResponseBody
    def delStudent(@RequestParam('_ids') List<String> _ids) {
        //遍历删除学生
        boolean flag = false
        DBObject student = null, user = null
        _ids.each { _id ->
            student = studentService.findOneById(_id)
            user = userService.findOneByQuery([identity: _id] as BasicDBObject)
            userService.deleteOne(user._id)
            flag = studentService.deleteOne(_id)
        }
        ResultUtil.recallAjax(flag)
    }

    /**
     * 修改学生
     * @param _id
     * @param name
     * @param phone
     * @param identityCard
     * @return
     */
    @RequestMapping("updateStudent")
    @ResponseBody
    def updateStudent(String _id, String name, String phone, String identityCard, Integer status) {
        //创建学生信息
        def teachers = studentService.findAllTeacherForStudent(_id),
            lessons = studentService.findAllLessonForStudent(_id),
            payInfo = payLogService.findListByQuery([student: _id] as BasicDBObject)
        Map<String, Object> studentInfo = [_id         : _id,
                                           name        : name,
                                           phone       : phone,
                                           identityCard: identityCard,
                                           status      : status,
                                           teachers    : teachers,
                                           lessons     : lessons,
                                           payInfo     : payInfo]
        DBObject dbObject = ToDBObjectUtil.toDBObject(studentInfo)
        boolean flag = studentService.updateOne(studentInfo._id, dbObject)
        ResultUtil.recallAjax(flag)
    }

    /**
     * 显示学生信息
     * @param studentId
     * @param model
     * @return
     */
    @RequestMapping("info")
    def findStudent(String studentId, Model model) {
        def student = studentService.findOneById(studentId)
        def studentMap = studentArgs(student)
        model.addAttribute("student", studentMap)
        return "student/info"
    }

    /**
     * 配置学生资源
     * @param studentId
     * @param model
     * @return
     */
    @RequestMapping("configure")
    def configure(String studentId, Model model) {
        List<DBObject> allLesson = lessonService.findList(),
                       lessonList = new ArrayList<>(), noLesson
        DBObject student = studentService.findOneById(studentId), lesson
        student.lessons.each {
            lesson = lessonService.findOneById(it.id)
            if (allLesson.contains(lesson)) {
                lessonList.add(lesson)
            }
        }
        if (lessonList.size() != 0) {
            allLesson.removeAll(lessonList)
        }
        noLesson = allLesson
        model.addAttribute("student", student)
        model.addAttribute("lessons", lessonList)
        model.addAttribute("noLessons", noLesson)
        return "student/configure"
    }

    /**
     * 给学生绑定课程
     * @param _ids
     * @param studentId
     * @return
     */
    @RequestMapping("bindLesson")
    @ResponseBody
    def bindLesson(@RequestParam('_ids') List<String> _ids,
                   @RequestParam('studentId') String studentId) {
        boolean flag = false
        _ids.each { _id ->
            flag = studentService.bindLessonForStudent(studentId, _id)
        }
        ResultUtil.recallAjax(flag)
    }

    /**
     * 给学生解除课程
     * @param _ids
     * @param studentId
     * @return
     */
    @RequestMapping("removeLesson")
    @ResponseBody
    def removeLesson(@RequestParam('_ids') List<String> _ids,
                     @RequestParam('studentId') String studentId) {
        boolean flag = false
        _ids.each { _id ->
            flag = studentService.removeLessonForStudent(studentId, _id)
        }
        ResultUtil.recallAjax(flag)
    }

    /**
     * 查找学生拥有课程
     * @param studentInfo
     * @return
     */
    @RequestMapping('findLessons')
    @ResponseBody
    def findLessons(String student) {
        def lessons = studentService.findAllLessonForStudent(student)
        return [msg: 'success', data: lessons]
    }

    @RequestMapping("lessons")
    def lessons(String student, Model model) {
        def lessons = studentService.findAllLessonForStudent(student)
        def list = new ArrayList(), map = new HashMap()
        lessons.each {
            map = ["id": it.id, "name": it.name, "n": it.n]
            list.add(map)
        }
        model.addAttribute("studentId", student)
        model.addAttribute("studentName",this.studentService.findOneById(student).name)
        model.addAttribute("lessons", list)
        return "student/lessons"
    }

    @RequestMapping("updateLesson")
    @ResponseBody
    def updateLesson(@RequestParam('studentId') String studentId, @RequestParam('lessonId') String lessonId,
                     @RequestParam('n') int n) {
        def lessons = studentService.findAllLessonForStudent(studentId)
        def list = new ArrayList(), obj = new BasicDBObject()
        def flag = false
        lessons.each {
            obj = it
            if (lessonId.equals(it.id)) {
                obj.n = n
            }
            list.add(obj)
        }
        flag = studentService.updateLessonForStudent(studentId, list)
        ResultUtil.recallAjax(flag)
    }

    /*************方法模块***************/

    def saveStudent(DBObject studentInfo) {
        ArgsUtil.checkArgs(studentInfo)
        //判断学生是否存在
        def query = [] as BasicDBObject
        query.append("name", studentInfo.name)
        DBObject student_db = studentService.findOneByQuery(query)
        if (student_db == null) {
            studentService.insertOne(studentInfo)
            return true
        } else {
            return false
        }
    }

    def select(Model model) {
        def teacherList = teacherService.findList() as LinkedList
        def lessonList = lessonService.findList() as LinkedList
        model.addAttribute("teachers", teacherList)
        model.addAttribute("lessons", lessonList)
    }

    def saveUser(DBObject userInfo) {
        ArgsUtil.checkArgs(userInfo)
        // 判断用户名是否存在
        DBObject user_db = userService.findUserByName(userInfo.username)
        if (user_db == null) {
            // 用户名不存在，可以创建用户
            // 新增用户
            String md5Password = MD5Util.md5(userInfo.password)
            userInfo.put("password", md5Password)
            userInfo.put("registerTime", new Date(System.currentTimeMillis()))
            userService.insertOne(userInfo)
            return true
        } else {
            // 用户名已存在
            return false
        }
    }

    def addStudentToUser(String name, String phone, String identity) {
        List<String> role = new LinkedList<>()
        role.add("69c80d0c-72b8-476e-aa28-072e004dad30")
        def pwd = phone
        if(phone == null || StringUtils.isEmpty(phone)){
            pwd = SystemConstant.DEFAULT_PASSWORD
        }
        Map<String, Object> userInfo = [_id     : UUID.randomUUID().toString(),
                                        username: name,
                                        password: pwd,
                                        email   : phone,
                                        status  : SystemConstant.USER_ON_JOB,
                                        role    : role,
                                        identity: identity,
                                        degree  : "student"
        ]
        DBObject dbObject = ToDBObjectUtil.toDBObject(userInfo)
        saveUser(dbObject)
    }

    def studentListArgs(List<DBObject> studentList) {
        Map<String, Object> studentMap = new HashMap<>()
        DBObject teacher, lesson
        List<DBObject> payInfo = new ArrayList<>()
        List<Map<String, Object>> studentMaps = new ArrayList<>()
        studentList.each {
            teacher = teacherService.findOneById(it.teacher)
            lesson = lessonService.findOneById(it.lesson)
            studentMap.put("_id", it._id)
            studentMap.put("name", it.name)
            studentMap.put("phone", it.phone)
            studentMap.put("identityCard", it.identityCard)
            studentMap.put("teacher", teacher)
            studentMap.put("lesson", lesson)
            studentMap.put("payInfo", payInfo)
            studentMaps.add(studentMap)
            studentMap = new HashMap<>()
        }
        return studentMaps
    }

    def studentArgs(DBObject student) {
        Map<String, Object> studentMap = new HashMap<>()
        List<DBObject> teacherList = studentService.findAllTeacherForStudent(student._id),
                       teachers = new ArrayList<>(),
                       lessonList = studentService.findAllLessonForStudent(student._id),
                       payInfo = new ArrayList<>()
        def lessons = new ArrayList<>()
        teacherList.each {
            teachers.add(teacherService.findOneById(it))
        }
        lessonList.each {
            def num = it.n
            if (num < 0) {
                lessons.add(it.name + "欠费超过" + (-1 * num) + "节")
            } else {
                lessons.add(it.name + "剩余课程" + num + "节")
            }
        }
        studentMap.put("_id", student._id)
        studentMap.put("name", student.name)
        studentMap.put("phone", student.phone)
        studentMap.put("identityCard", student.identityCard)
        studentMap.put("teacher", teachers)
        studentMap.put("lessons", lessons)
        studentMap.put("payInfo", payInfo)
        return studentMap
    }

}
